package com.citcc.api.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.citcc.api.netty.bean.ConsuMessage;
import com.citcc.api.netty.server.ServerToClient;
import com.citcc.api.netty.utils.CommandUtil;
import com.citcc.api.utils.WeiXinPayUtil;
import com.citcc.business.bean.AlipayRefundInfo;
import com.citcc.business.bean.CdzOrderRefundEntity;
import com.citcc.business.bean.PayResult;
import com.citcc.business.bean.UserOrderEntity;
import com.citcc.business.mapper.CdzOrderRefundEntityMapper;
import com.citcc.business.service.ScanCodeService;
import com.citcc.business.util.IdGenerator;
import org.apache.commons.collections4.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: qinbo
 * Date: 2019/4/10
 * Time: 11:50
 * Description:
 */
@RestController
public class PayNotifyController {
    private Logger logger = LoggerFactory.getLogger(PayNotifyController.class);
    String randomString = WeiXinPayUtil.getRandomString(32);
    @Autowired
    private ScanCodeService scanCodeService;
    @Autowired
    private ServerToClient serverToClient;
    @Value("${pay.zhifubao.apppay.privateKey}")
    private String privateKey;
    @Value("${pay.zhifubao.apppay.publicKey}")
    private String publicKey;

    @Value("${pay.zhifubao.apppay.appid}")
    private String appid;
    @Value("${pay.zhifubao.apppay.requesturl}")
    private String requesturl;

    @Autowired
    private CdzOrderRefundEntityMapper cdzOrderRefundEntityMapper;

    @RequestMapping(value = "/weixin/notify",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public String depostwxpaySucc(HttpServletRequest request) throws IOException {
        DecimalFormat fomart = new DecimalFormat("0.00");
        logger.info("微信支付回调");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        Map<String, String> params = null;
        try {
            String resultxml = new String(outSteam.toByteArray(), "utf-8");
            logger.info("resultxml=  "+resultxml);
            params = WeiXinPayUtil.xmlToMap(resultxml);
        } catch (Exception e) {
            e.printStackTrace();
            return "FAIL";
        }
        logger.info(params.toString());
        outSteam.close();
        inStream.close();
        Map<String, String> data = new HashedMap();
        String attach = params.get("attach");
        String out_trade_no = params.get("out_trade_no");

        logger.info("回调订单号---------" + out_trade_no);
        String totalfee = params.get("total_fee");
        logger.info("totalfee"+totalfee);
        String tradeno = params.get("transaction_id");
        //根据订单号查询订单
        UserOrderEntity userOrderEntity = scanCodeService.selectOrderByOrderNum(out_trade_no);
        if (userOrderEntity == null) {
            return "SUCCESS";
        }
        String tradeType = userOrderEntity.getType();
        logger.info("交易业务类型：" + tradeType);
        try {
            JSONObject jsonObject = JSONObject.parseObject(attach);
            Map<String, Object> map = (Map<String, Object>) jsonObject;
            logger.info(map + "----------map");
            if ("wx-app-pay".equals(tradeType)) {
                logger.info("===============充值话费支付回调==============");
                //String orderNumber, String userId, String payState
                if (!WeiXinPayUtil.isTenpaySign(params)) {
                    logger.info("===============付款成功签名失败回调==============");
                    logger.info("回调订单状态"+userOrderEntity.getChargeState());
                    if (com.citcc.common.utils.StringUtils.isNotEmpty(userOrderEntity.getChargeState())){
                        logger.info("回调订单状态非null");
                        return "SUCCESS";
                    }
                    userOrderEntity.setPayState("2");
                    userOrderEntity.setChargeState("1");
                    userOrderEntity.setTradeNo(tradeno);
                    Long time=System.currentTimeMillis();
                  /*  BigDecimal chargeLong = userOrderEntity.getPayNumber();
                    BigDecimal multiply = chargeLong.multiply(new BigDecimal(3600 * 1000));*/
                    userOrderEntity.setStartTime(new Date(time));
                 //   userOrderEntity.setEndTime(new Date(time+multiply.longValue()));
                    scanCodeService.updatePayStateAndGun(userOrderEntity);
                    //开启
                   /* long l = userOrderEntity.getChargeLong().longValue();
                    int cmd = CommandUtil.cmd(userOrderEntity.getStakeCode(), userOrderEntity.getGunCode(), userOrderEntity.getUserPhone(), l);*/
                    ConsuMessage consuMessage=new ConsuMessage();
                    consuMessage.setDeviceNo(Long.parseLong(userOrderEntity.getStakeCode()));
                    consuMessage.setSource(Integer.parseInt(userOrderEntity.getGunCode()));
                    consuMessage.setPhone(userOrderEntity.getUserPhone());
                    consuMessage.setMoney(userOrderEntity.getPayNumber().multiply(new BigDecimal(100)).longValue());
                    consuMessage.setMode("0");
                    int i = serverToClient.startCmd(consuMessage);
                    if (i!=200){
                        BigDecimal total = new BigDecimal(totalfee).divide(new BigDecimal(100));
                        String id=IdGenerator.generateId();
                        CdzOrderRefundEntity cdzOrderRefund=new CdzOrderRefundEntity();
                        cdzOrderRefund.setId(id);
                        cdzOrderRefund.setAmount(total);

                        cdzOrderRefund.setRefundPrice(total);
                        cdzOrderRefund.setTradeNo(tradeno);
                        cdzOrderRefund.setPayType("1");
                        cdzOrderRefund.setCreator(userOrderEntity.getUserId());
                        cdzOrderRefund.setModifier(userOrderEntity.getUserId());
                        cdzOrderRefund.setUserId(cdzOrderRefund.getUserId());
                        cdzOrderRefund.setCreateDate(new Date());
                        cdzOrderRefund.setUpdateDate(new Date());
                        cdzOrderRefund.setDelFlag("0");
                        cdzOrderRefund.setRefundOrderId(out_trade_no);
                        cdzOrderRefund.setRefundReason("设备通讯中断");
                        Map<String, String> stringStringMap = this.doRefund(tradeno,new BigDecimal(totalfee) , id);
                        logger.info(stringStringMap.get("return_code"));
                        logger.info(stringStringMap.get("return_msg"));
                        String err_code = stringStringMap.get("err_code");
                        String err_code_des = stringStringMap.get("err_code_des");
                        String return_code = stringStringMap.get("return_code");
                        String return_msg = stringStringMap.get("return_msg");
                        cdzOrderRefund.setCode(return_code);
                        cdzOrderRefund.setMsg(return_msg);
                        cdzOrderRefund.setSubCode(err_code);
                        cdzOrderRefund.setSubMsg(err_code_des);
                        if ("SUCCESS".equals(stringStringMap.get("return_code"))) {
                            logger.info(stringStringMap.get("err_code"));
                            logger.info(stringStringMap.get("err_code_des"));
                            logger.info(stringStringMap.get("out_trade_no"));
                            logger.info(stringStringMap.get("transaction_id"));
                            logger.info(stringStringMap.get("total_fee"));
                            logger.info(stringStringMap.get("out_refund_no"));
                            logger.info(stringStringMap.get("refund_id"));
                            if (com.citcc.common.utils.StringUtils.isNotEmpty(err_code)){
                                logger.info("退款失败");
                                cdzOrderRefund.setState("1");
                                logger.info(err_code_des);
                            }else {
                                cdzOrderRefund.setState("0");
                            }

                        }else {
                            logger.info("退款失败");
                            cdzOrderRefund.setState("1");
                        }
                        cdzOrderRefundEntityMapper.insert(cdzOrderRefund);
                        userOrderEntity.setChargeState("3");
                        scanCodeService.updatePayStateAndGunYC(userOrderEntity);
                    }
                    logger.info("支付成功，开启结果==="+i);
                    return "SUCCESS";
                } else {
                    data.put("return_code", "SUCCESS");
                    logger.info("===============付款成功回调==============");
                    logger.info("回调订单状态"+userOrderEntity.getChargeState());
                    if (com.citcc.common.utils.StringUtils.isNotEmpty(userOrderEntity.getChargeState())){
                        logger.info("回调订单状态"+userOrderEntity.getChargeState());
                        return "SUCCESS";
                    }
                    //修改支付成功
                    userOrderEntity.setPayState("2");
                    userOrderEntity.setChargeState("1");
                    userOrderEntity.setTradeNo(tradeno);
                    Long time=System.currentTimeMillis();
                 /*   BigDecimal chargeLong = userOrderEntity.getChargeLong();
                    BigDecimal multiply = chargeLong.multiply(new BigDecimal(3600 * 1000));*/
                    userOrderEntity.setStartTime(new Date(time));
                 //   userOrderEntity.setEndTime(new Date(time+multiply.longValue()));
                    scanCodeService.updatePayStateAndGun(userOrderEntity);
                    //开启
                  /*  long l = userOrderEntity.getChargeLong().longValue();
                    int cmd = CommandUtil.cmd(userOrderEntity.getStakeCode(), userOrderEntity.getGunCode(), userOrderEntity.getUserPhone(), l);
                    logger.info("支付成功，开启结果==="+cmd);*/
                    ConsuMessage consuMessage=new ConsuMessage();
                    consuMessage.setDeviceNo(Long.parseLong(userOrderEntity.getStakeCode()));
                    consuMessage.setSource(Integer.parseInt(userOrderEntity.getGunCode()));
                    consuMessage.setPhone(userOrderEntity.getUserPhone());
                    consuMessage.setMoney(userOrderEntity.getPayNumber().multiply(new BigDecimal(100)).longValue());
                    consuMessage.setMode("1");
                   int i = serverToClient.startCmd(consuMessage);
                    if (i!=200){
                        BigDecimal total = new BigDecimal(totalfee).divide(new BigDecimal(100));

                        String id=IdGenerator.generateId();
                        CdzOrderRefundEntity cdzOrderRefund=new CdzOrderRefundEntity();
                        cdzOrderRefund.setId(id);
                        cdzOrderRefund.setAmount(total);

                        cdzOrderRefund.setRefundPrice(total);
                        cdzOrderRefund.setTradeNo(tradeno);
                        cdzOrderRefund.setPayType("1");
                        cdzOrderRefund.setCreator(userOrderEntity.getUserId());
                        cdzOrderRefund.setModifier(userOrderEntity.getUserId());
                        cdzOrderRefund.setUserId(cdzOrderRefund.getUserId());
                        cdzOrderRefund.setCreateDate(new Date());
                        cdzOrderRefund.setUpdateDate(new Date());
                        cdzOrderRefund.setDelFlag("0");
                        cdzOrderRefund.setRefundOrderId(out_trade_no);
                        cdzOrderRefund.setRefundReason("设备通讯中断");
                        Map<String, String> stringStringMap = this.doRefund(tradeno,new BigDecimal(totalfee) , id);
                        logger.info(stringStringMap.get("return_code"));
                        logger.info(stringStringMap.get("return_msg"));
                        String err_code = stringStringMap.get("err_code");
                        String err_code_des = stringStringMap.get("err_code_des");
                        String return_code = stringStringMap.get("return_code");
                        String return_msg = stringStringMap.get("return_msg");
                        cdzOrderRefund.setCode(return_code);
                        cdzOrderRefund.setMsg(return_msg);
                        cdzOrderRefund.setSubCode(err_code);
                        cdzOrderRefund.setSubMsg(err_code_des);
                        if ("SUCCESS".equals(stringStringMap.get("return_code"))) {
                            logger.info(err_code);
                            logger.info(stringStringMap.get("err_code_des"));
                            logger.info(stringStringMap.get("out_trade_no"));
                            logger.info(stringStringMap.get("transaction_id"));
                            logger.info(stringStringMap.get("total_fee"));
                            logger.info(stringStringMap.get("out_refund_no"));
                            logger.info(stringStringMap.get("refund_id"));
                            logger.info("退款成功");
                            if (com.citcc.common.utils.StringUtils.isNotEmpty(err_code)){
                                logger.info("退款失败");
                                cdzOrderRefund.setState("1");
                                logger.info(err_code_des);
                            }else {
                                cdzOrderRefund.setState("0");
                            }
                        }else {
                            logger.info("退款失败");
                            cdzOrderRefund.setState("1");
                        }
                        cdzOrderRefundEntityMapper.insert(cdzOrderRefund);
                        userOrderEntity.setChargeState("3");
                        scanCodeService.updatePayStateAndGunYC(userOrderEntity);
                    }
                    logger.info("支付成功，开启结果==="+i);
                    return "SUCCESS";
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e + "");
            logger.info(" // 处理异常");
            // 支付失败
            return "FAIL";
        }
        return "FAIL";
    }

    /**
     * 支付宝支付成功后.回调该接口
     *
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/alipay/notify", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        DecimalFormat fomart = new DecimalFormat("0.00");
        Map<String, String> params = new HashMap<String, String>();
        // Trade trade =null;
        //1.从支付宝回调的request域中取值
        Map<String, String[]> requestParams = request.getParameterMap();

        logger.info("---------------jinru");
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        logger.info(requestParams + "requestParams--------------");
        //2.封装必须参数
        String out_trade_no = request.getParameter("out_trade_no");            // 商户订单号
        String orderType = request.getParameter("body");                    // 订单内容
        String tradeStatus = request.getParameter("trade_status");            //交易状态
        String passback_params = request.getParameter("passback_params");            //交易状态
        String total_amount = request.getParameter("total_amount");            //交易状态
        String trade_no = request.getParameter("trade_no");            //支付宝交易号
        String notify_type = request.getParameter("notify_type");            //支付宝交易号
        logger.info(tradeStatus + "tradeStatus");
        logger.info(trade_no + "=========trade_no");
        logger.info(out_trade_no + "=========out_trade_no");
        logger.info(total_amount + "=========total_amount");
        try {
            //
            UserOrderEntity userOrderEntity = scanCodeService.selectOrderByOrderNum(out_trade_no);
            if (userOrderEntity == null) {
                logger.info("未找到对应订单");
                return "success";
            }
            String tradeType = userOrderEntity.getType();
            logger.info("交易业务类型：" + tradeType);
            //（0：支付宝，1：微信）
            boolean signVerified = false;
            //3.1调用SDK验证签名
            signVerified = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", "RSA2");
            switch (tradeType) {
                case "zfb-app-pay":
                    logger.info("===============zfb-app-pay 支付宝支付（充值话费）回调==============");
                    if (signVerified) {    //验签通过
                        System.err.println("验签通过");
                        if (tradeStatus.equals("TRADE_SUCCESS")) {    //只处理支付成功的订单: 修改交易表状态,支付成功45dc5721abaa4cfa9ecbf48d6341bc2d
                            logger.info("===============付款成功回调==============");
                            logger.info("回调订单状态"+userOrderEntity.getChargeState());
                            if (com.citcc.common.utils.StringUtils.isNotEmpty(userOrderEntity.getChargeState())){
                                logger.info("duoci回调订单状态"+userOrderEntity.getChargeState());
                                return "success";
                            }
                            userOrderEntity.setPayState("2");
                            userOrderEntity.setChargeState("1");
                            userOrderEntity.setTradeNo(trade_no);
                            userOrderEntity.setUpdateTime(new Date());
                            Long time=System.currentTimeMillis();
                         /*   BigDecimal chargeLong = userOrderEntity.getChargeLong();
                            BigDecimal multiply = chargeLong.multiply(new BigDecimal(3600 * 1000));*/
                            userOrderEntity.setStartTime(new Date(time));
                           // userOrderEntity.setEndTime(new Date(time+multiply.longValue()));
                            scanCodeService.updatePayStateAndGun(userOrderEntity);
/*
                            //开启
                            long l = userOrderEntity.getChargeLong().longValue();
                            int cmd = CommandUtil.cmd(userOrderEntity.getStakeCode(), userOrderEntity.getGunCode(), userOrderEntity.getUserPhone(), l);
                            logger.info("支付成功，开启结果==="+cmd);*/
                            ConsuMessage consuMessage=new ConsuMessage();
                            consuMessage.setDeviceNo(Long.parseLong(userOrderEntity.getStakeCode()));
                            consuMessage.setSource(Integer.parseInt(userOrderEntity.getGunCode()));
                            consuMessage.setPhone(userOrderEntity.getUserPhone());
                            consuMessage.setMoney(userOrderEntity.getPayNumber().multiply(new BigDecimal(100)).longValue());
                            consuMessage.setMode("1");
                            int i = serverToClient.startCmd(consuMessage);
                            if (i!=200){
                                String id=IdGenerator.generateId();
                                CdzOrderRefundEntity cdzOrderRefund=new CdzOrderRefundEntity();
                                cdzOrderRefund.setId(id);
                                cdzOrderRefund.setAmount(new BigDecimal(total_amount));

                                cdzOrderRefund.setRefundPrice(new BigDecimal(total_amount));
                                cdzOrderRefund.setTradeNo(trade_no);
                                cdzOrderRefund.setPayType("0");
                                cdzOrderRefund.setCreator(userOrderEntity.getUserId());
                                cdzOrderRefund.setModifier(userOrderEntity.getUserId());
                                cdzOrderRefund.setUserId(cdzOrderRefund.getUserId());
                                cdzOrderRefund.setCreateDate(new Date());
                                cdzOrderRefund.setUpdateDate(new Date());
                                cdzOrderRefund.setDelFlag("0");
                                cdzOrderRefund.setRefundOrderId(out_trade_no);
                                cdzOrderRefund.setRefundReason("设备通讯中断");
                                AlipayClient alipayClient = new DefaultAlipayClient
                                        (requesturl, appid,
                                                privateKey, "json", "GBK", publicKey, "RSA2");
                                AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
                                AlipayRefundInfo alidata = new AlipayRefundInfo();
                                alidata.setRefund_amount(new BigDecimal(total_amount));
                                alidata.setTrade_no(trade_no);
                                alidata.setOut_request_no(id);
                                alipayTradeRefundRequest.setBizContent(JSONObject.toJSONString(alidata));
                                AlipayTradeRefundResponse alipayTradeRefundResponse = alipayClient.execute(alipayTradeRefundRequest);
                                logger.info("支付宝账号：" + alipayTradeRefundResponse.getBuyerLogonId());
                                String code = alipayTradeRefundResponse.getCode();
                                String msg = alipayTradeRefundResponse.getMsg();
                                String subCode = alipayTradeRefundResponse.getSubCode();
                                String subMsg = alipayTradeRefundResponse.getSubMsg();
                                logger.info("网关返回码====="+code);
                                logger.info("网关返回码描述====="+msg);
                                logger.info("业务返回码====="+subCode);
                                logger.info("业务返回码描述====="+subMsg);
                                cdzOrderRefund.setCode(code);
                                cdzOrderRefund.setMsg(msg);
                                cdzOrderRefund.setSubCode(subCode);
                                cdzOrderRefund.setSubMsg(subMsg);
                                if ("10000".equals(alipayTradeRefundResponse.getCode())) {
                                    if (com.citcc.common.utils.StringUtils.isNotEmpty(subCode)|| com.citcc.common.utils.StringUtils.isNotEmpty(subMsg)){
                                        logger.info("退款失败");
                                        cdzOrderRefund.setState("1");
                                    }else {
                                        logger.info("退款成功");
                                        cdzOrderRefund.setState("0");
                                    }
                                }else {
                                    logger.info("退款失败");
                                    cdzOrderRefund.setState("1");
                                }
                                cdzOrderRefundEntityMapper.insert(cdzOrderRefund);
                                userOrderEntity.setChargeState("3");
                                scanCodeService.updatePayStateAndGunYC(userOrderEntity);
                            }
                            logger.info("支付成功，开启结果==="+i);
                        }
                        return "success";
                    } else {  //验签不通过
                        logger.info("===============付款成功签名失败回调==============");
                        logger.info("回调订单状态"+userOrderEntity.getChargeState());
                        if (com.citcc.common.utils.StringUtils.isNotEmpty(userOrderEntity.getChargeState())){
                            return "success";
                        }
                        System.err.println("验签失败");
                        userOrderEntity.setPayState("2");
                        userOrderEntity.setChargeState("1");
                        userOrderEntity.setTradeNo(trade_no);
                        userOrderEntity.setUpdateTime(new Date());
                        Long time=System.currentTimeMillis();
                       /* BigDecimal chargeLong = userOrderEntity.getChargeLong();
                        BigDecimal multiply = chargeLong.multiply(new BigDecimal(3600 * 1000));*/
                        userOrderEntity.setStartTime(new Date(time));
                       // userOrderEntity.setEndTime(new Date(time+multiply.longValue()));
                        scanCodeService.updatePayStateAndGun(userOrderEntity);

                     /*   //开启
                        long l = userOrderEntity.getChargeLong().longValue();
                        int cmd = CommandUtil.cmd(userOrderEntity.getStakeCode(), userOrderEntity.getGunCode(), userOrderEntity.getUserPhone(), l);
                        logger.info("支付成功，开启结果==="+cmd);*/
                        ConsuMessage consuMessage=new ConsuMessage();
                        consuMessage.setDeviceNo(Long.parseLong(userOrderEntity.getStakeCode()));
                        consuMessage.setSource(Integer.parseInt(userOrderEntity.getGunCode()));
                        consuMessage.setPhone(userOrderEntity.getUserPhone());
                        consuMessage.setMoney(userOrderEntity.getPayNumber().multiply(new BigDecimal(100)).longValue());
                        consuMessage.setMode("1");
                        int i = serverToClient.startCmd(consuMessage);
                        if (i!=200){
                            //退款
                            String id=IdGenerator.generateId();
                            CdzOrderRefundEntity cdzOrderRefund=new CdzOrderRefundEntity();
                            cdzOrderRefund.setId(id);
                            cdzOrderRefund.setAmount(new BigDecimal(total_amount));

                            cdzOrderRefund.setRefundPrice(new BigDecimal(total_amount));
                            cdzOrderRefund.setTradeNo(trade_no);
                            cdzOrderRefund.setPayType("0");
                            cdzOrderRefund.setCreator(userOrderEntity.getUserId());
                            cdzOrderRefund.setModifier(userOrderEntity.getUserId());
                            cdzOrderRefund.setUserId(cdzOrderRefund.getUserId());
                            cdzOrderRefund.setCreateDate(new Date());
                            cdzOrderRefund.setUpdateDate(new Date());
                            cdzOrderRefund.setDelFlag("0");
                            cdzOrderRefund.setRefundOrderId(out_trade_no);
                            cdzOrderRefund.setRefundReason("设备通讯中断");
                            AlipayClient alipayClient = new DefaultAlipayClient
                                    (requesturl, appid,
                                            privateKey, "json", "GBK", publicKey, "RSA2");
                            AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
                            AlipayRefundInfo alidata = new AlipayRefundInfo();
                            alidata.setRefund_amount(new BigDecimal(total_amount));
                            alidata.setTrade_no(trade_no);
                            alidata.setOut_request_no(id);
                            alipayTradeRefundRequest.setBizContent(JSONObject.toJSONString(alidata));
                            AlipayTradeRefundResponse alipayTradeRefundResponse = alipayClient.execute(alipayTradeRefundRequest);
                            logger.info("支付宝账号：" + alipayTradeRefundResponse.getBuyerLogonId());

                            String code = alipayTradeRefundResponse.getCode();
                            String msg = alipayTradeRefundResponse.getMsg();
                            String subCode = alipayTradeRefundResponse.getSubCode();
                            String subMsg = alipayTradeRefundResponse.getSubMsg();
                            logger.info("网关返回码====="+code);
                            logger.info("网关返回码描述====="+msg);
                            logger.info("业务返回码====="+subCode);
                            logger.info("业务返回码描述====="+subMsg);
                            cdzOrderRefund.setCode(code);
                            cdzOrderRefund.setMsg(msg);
                            cdzOrderRefund.setSubCode(subCode);
                            cdzOrderRefund.setSubMsg(subMsg);
                            if ("10000".equals(alipayTradeRefundResponse.getCode())) {
                                if (com.citcc.common.utils.StringUtils.isNotEmpty(subCode)|| com.citcc.common.utils.StringUtils.isNotEmpty(subMsg)){
                                    logger.info("退款失败");
                                    cdzOrderRefund.setState("1");
                                }else {
                                    logger.info("退款成功");
                                    cdzOrderRefund.setState("0");
                                }
                            }else {
                                logger.info("退款失败");
                                cdzOrderRefund.setState("1");
                            }
                            cdzOrderRefundEntityMapper.insert(cdzOrderRefund);
                            userOrderEntity.setChargeState("3");
                            scanCodeService.updatePayStateAndGunYC(userOrderEntity);
                        }
                        logger.info("支付成功，开启结果==="+i);
                        return "success";
                    }
                default:
                    return "success";
            }


        } catch (Exception e) {
            logger.info("===============付款成功异常处理回调==============");
            e.printStackTrace();
            return "success";
        }
    }


    /**
     * 退款參數封装
     */
    public Map<String, String> doRefund(String transaction_id, BigDecimal total_fee, String id) {

        logger.info("------------封装");
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        parameterMap.put("appid", WeiXinPayUtil.APPID);
        parameterMap.put("mch_id", WeiXinPayUtil.MCH_ID);
        parameterMap.put("nonce_str", randomString);
        parameterMap.put("transaction_id", transaction_id);
        parameterMap.put("out_refund_no", id);
        parameterMap.put("refund_fee_type", "CNY");
        logger.info("jiner");
        java.text.DecimalFormat df = new java.text.DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total_fee));
        parameterMap.put("refund_fee", df.format(total_fee));
        String sign = WeiXinPayUtil.createSign("UTF-8", parameterMap);
        logger.info("jiner2");
        parameterMap.put("sign", sign);
        String result = null;
        Map<String, String> map = null;
        try {
            String requestXML = WeiXinPayUtil.mapToXml(parameterMap);
            logger.info(requestXML);
            result = WeiXinPayUtil.httpsRequest2(
                    "https://api.mch.weixin.qq.com/secapi/pay/refund", "POST",
                    requestXML);
            map = WeiXinPayUtil.xmlToMap(result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 退款參數封装
     */
    public Map<String, String> doRefundPart(String transaction_id, BigDecimal total_fee, String id,BigDecimal refundNum) {

        logger.info("------------封装");
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        parameterMap.put("appid", WeiXinPayUtil.APPID);
        parameterMap.put("mch_id", WeiXinPayUtil.MCH_ID);
        parameterMap.put("nonce_str", randomString);
        parameterMap.put("transaction_id", transaction_id);
        parameterMap.put("out_refund_no", id);
        parameterMap.put("refund_fee_type", "CNY");
        logger.info("jiner");
        java.text.DecimalFormat df = new java.text.DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total_fee));
        parameterMap.put("refund_fee", df.format(refundNum));
        String sign = WeiXinPayUtil.createSign("UTF-8", parameterMap);
        logger.info("jiner2");
        parameterMap.put("sign", sign);
        String result = null;
        Map<String, String> map = null;
        try {
            String requestXML = WeiXinPayUtil.mapToXml(parameterMap);
            logger.info(requestXML);
            result = WeiXinPayUtil.httpsRequest2(
                    "https://api.mch.weixin.qq.com/secapi/pay/refund", "POST",
                    requestXML);
            map = WeiXinPayUtil.xmlToMap(result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return map;
    }
    
    public void refundRequest(String type, String transaction_id,BigDecimal refund_amount,BigDecimal amount,
    		String userId,String outTradeNo,String id) throws Exception{
    	logger.info("支付流水号:"+transaction_id+"-->付款:"+amount+"-->退款金额:"+refund_amount+"-->类型:"+type+"-->id:"+id);
    	if("wx".equals(type)){
    		CdzOrderRefundEntity cdzOrderRefund=new CdzOrderRefundEntity();
            cdzOrderRefund.setId(id);
            cdzOrderRefund.setAmount(amount);

            cdzOrderRefund.setRefundPrice(refund_amount);
            cdzOrderRefund.setTradeNo(transaction_id);
            cdzOrderRefund.setPayType("1");//weixin
            cdzOrderRefund.setCreator(userId);
            cdzOrderRefund.setModifier(userId);
            cdzOrderRefund.setUserId(userId);
            cdzOrderRefund.setCreateDate(new Date());
            cdzOrderRefund.setUpdateDate(new Date());
            cdzOrderRefund.setDelFlag("0");
            cdzOrderRefund.setRefundOrderId(outTradeNo);
            cdzOrderRefund.setRefundReason("充电费用未用完");
            Map<String, String> stringStringMap = this.doRefundPart(transaction_id,amount.multiply(new BigDecimal(100)),id,refund_amount.multiply(new BigDecimal(100)));
            logger.info(stringStringMap.get("return_code"));
            logger.info(stringStringMap.get("return_msg"));
            String err_code = stringStringMap.get("err_code");
            String err_code_des = stringStringMap.get("err_code_des");
            String return_code = stringStringMap.get("return_code");
            String return_msg = stringStringMap.get("return_msg");
            cdzOrderRefund.setCode(return_code);
            cdzOrderRefund.setMsg(return_msg);
            cdzOrderRefund.setSubCode(err_code);
            cdzOrderRefund.setSubMsg(err_code_des);
            if ("SUCCESS".equals(stringStringMap.get("return_code"))) {
                logger.info(stringStringMap.get("err_code"));
                logger.info(stringStringMap.get("err_code_des"));
                logger.info(stringStringMap.get("out_trade_no"));
                logger.info(stringStringMap.get("transaction_id"));
                logger.info(stringStringMap.get("total_fee"));
                logger.info(stringStringMap.get("out_refund_no"));
                logger.info(stringStringMap.get("refund_id"));
                if (com.citcc.common.utils.StringUtils.isNotEmpty(err_code)){
                    logger.info("退款失败");
                    cdzOrderRefund.setState("1");
                    logger.info(err_code_des);
                }else {
                    cdzOrderRefund.setState("0");
                }

            }else {
                logger.info("退款失败");
                cdzOrderRefund.setState("1");
            }
            cdzOrderRefundEntityMapper.insert(cdzOrderRefund);
    	}else if("zfb".equals(type)){
    		CdzOrderRefundEntity cdzOrderRefund=new CdzOrderRefundEntity();
            cdzOrderRefund.setId(id);
            cdzOrderRefund.setAmount(amount);

            cdzOrderRefund.setRefundPrice(refund_amount);
            cdzOrderRefund.setTradeNo(transaction_id);
            cdzOrderRefund.setPayType("0");
            cdzOrderRefund.setCreator(userId);
            cdzOrderRefund.setModifier(userId);
            cdzOrderRefund.setUserId(userId);
            cdzOrderRefund.setCreateDate(new Date());
            cdzOrderRefund.setUpdateDate(new Date());
            cdzOrderRefund.setDelFlag("0");
            cdzOrderRefund.setRefundOrderId(outTradeNo);
            cdzOrderRefund.setRefundReason("充电费用未用完");
            AlipayClient alipayClient = new DefaultAlipayClient
                    (requesturl, appid,
                            privateKey, "json", "GBK", publicKey, "RSA2");
            AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
            AlipayRefundInfo alidata = new AlipayRefundInfo();
            alidata.setRefund_amount(refund_amount);
            alidata.setTrade_no(transaction_id);
            alidata.setOut_request_no(id);
            alipayTradeRefundRequest.setBizContent(JSONObject.toJSONString(alidata));
            AlipayTradeRefundResponse alipayTradeRefundResponse = alipayClient.execute(alipayTradeRefundRequest);
            logger.info("支付宝账号：" + alipayTradeRefundResponse.getBuyerLogonId());
            String code = alipayTradeRefundResponse.getCode();
            String msg = alipayTradeRefundResponse.getMsg();
            String subCode = alipayTradeRefundResponse.getSubCode();
            String subMsg = alipayTradeRefundResponse.getSubMsg();
            logger.info("网关返回码====="+code);
            logger.info("网关返回码描述====="+msg);
            logger.info("业务返回码====="+subCode);
            logger.info("业务返回码描述====="+subMsg);
            cdzOrderRefund.setCode(code);
            cdzOrderRefund.setMsg(msg);
            cdzOrderRefund.setSubCode(subCode);
            cdzOrderRefund.setSubMsg(subMsg);
            if ("10000".equals(alipayTradeRefundResponse.getCode())) {
                if (com.citcc.common.utils.StringUtils.isNotEmpty(subCode)|| com.citcc.common.utils.StringUtils.isNotEmpty(subMsg)){
                    logger.info("退款失败");
                    cdzOrderRefund.setState("1");
                }else {
                    logger.info("退款成功");
                    cdzOrderRefund.setState("0");
                }
            }else {
                logger.info("退款失败");
                cdzOrderRefund.setState("1");
            }
            cdzOrderRefundEntityMapper.insert(cdzOrderRefund);
    	}
    }
}